#include "characterclass.h"
#include "characterclassskills.h"
#include "skill.h"
#include "specialability.h"
#include "specialabilitylevel.h"


#include <QDebug>


CharacterClass::CharacterClass(QObject *parent) :
    ModelItem(parent),
    m_hitDie(0),
    m_skillPoints(0),
    m_baseAttack(0),
    m_fortSave(0),
    m_refSave(0),
    m_willSave(0),
    m_levels(20)
{
    qRegisterMetaType<CharacterClassSkills*>();
}


CharacterClass::CharacterClass(const CharacterClass &other) :
    ModelItem(other)
{
    m_acronym = other.acronym();
    m_hitDie = other.hitDie();
    m_skillPoints = other.skillPoints();
    m_baseAttack = other.baseAttack();
    m_fortSave = other.fortSave();
    m_refSave = other.refSave();
    m_willSave = other.willSave();
    m_levels = other.levels();
}

int CharacterClass::hitDie() const
{
    return m_hitDie;
}

int CharacterClass::skillPoints() const
{
    return m_skillPoints;
}

int CharacterClass::baseAttack() const
{
    return m_baseAttack;
}

int CharacterClass::fortSave() const
{
    return m_fortSave;
}

int CharacterClass::refSave() const
{
    return m_refSave;
}

int CharacterClass::willSave() const
{
    return m_willSave;
}

QString CharacterClass::acronym() const
{
    if (m_acronym.isEmpty())
    {
        return name().left(3);
    }
    return m_acronym;
}


QStringList CharacterClass::classSkills() const
{
    QStringList ret;

    CharacterClassSkills* characterClassSkills = findChild<CharacterClassSkills*>(QString(), Qt::FindDirectChildrenOnly);
    if (!characterClassSkills)
    {
        return ret;
    }

    foreach (CharacterClassSkill* classSkillItem, characterClassSkills->findChildren<CharacterClassSkill*>(QString(), Qt::FindDirectChildrenOnly))
    {
        ret << classSkillItem->data("name").toString();
    }

    qSort(ret);

    return ret;
}

int CharacterClass::levels() const
{
    return m_levels;
}


QStringList CharacterClass::specialAbilities(int level) const
{
    QStringList ret;



    SpecialAbilities* specials = rootItem()->findChild<SpecialAbilities*>(QString(), Qt::FindDirectChildrenOnly);
    if (!specials)
    {
        qWarning() << Q_FUNC_INFO << "Special Abilities can't be found!";
        return ret;
    }

    foreach (const SpecialAbilityLevel* specialRef, specials->findChildren<const SpecialAbilityLevel*>())
    {
        SpecialAbility* special = qobject_cast<SpecialAbility*>(specialRef->parent()->parent());

//        qDebug() << special->name() << specialRef->referenceItem()->name() << specialRef->property("level");
        if (!special)
        {
            continue;
        }

        if (specialRef->referenceItem() != this)
        {
            continue;
        }

        if (specialRef->property("level").toInt() != level)
        {
            continue;
        }


//        qDebug() << Q_FUNC_INFO << "Found special ability" << special->name() << "for" << name() << "level" << level;

        ret << special->name();
    }

    return ret;
}




//bool CharacterClass::isClassSkill(const QString &skillName) const
//{
////    qDebug() << Q_FUNC_INFO << skillName << "?" << classSkills().join(";");
//    return classSkills().contains(skillName);
//}

void CharacterClass::setHitDie(int arg)
{
    if (m_hitDie != arg) {
        m_hitDie = arg;
        emit hitDieChanged(arg);
    }
}

void CharacterClass::setSkillPoints(int arg)
{
    if (m_skillPoints != arg) {
        m_skillPoints = arg;
        emit skillPointsChanged(arg);
    }
}

void CharacterClass::setBaseAttack(int arg)
{
    if (m_baseAttack != arg) {
        m_baseAttack = arg;
        emit baseAttackChanged(arg);
    }
}

void CharacterClass::setFortSave(int arg)
{
    if (m_fortSave != arg) {
        m_fortSave = arg;
        emit fortSaveChanged(arg);
    }
}

void CharacterClass::setRefSave(int arg)
{
    if (m_refSave != arg) {
        m_refSave = arg;
        emit refSaveChanged(arg);
    }
}

void CharacterClass::setWillSave(int arg)
{
    if (m_willSave != arg) {
        m_willSave = arg;
        emit willSaveChanged(arg);
    }
}

void CharacterClass::addClassSkill(Skill *skill)
{
    CharacterClassSkills* characterClassSkills = findChild<CharacterClassSkills*>(QString(), Qt::FindDirectChildrenOnly);

    if (!characterClassSkills)
    {
        characterClassSkills = new CharacterClassSkills(this);
    }

    foreach (CharacterClassSkill* classSkill, characterClassSkills->findChildren<CharacterClassSkill*>(QString(), Qt::FindDirectChildrenOnly))
    {
        if (classSkill->referenceItem() == skill)
        {
            return;
        }
    }

    CharacterClassSkill* classSkill = characterClassSkills->createItem();
    classSkill->setReferenceItem(skill);
}

void CharacterClass::setLevels(int arg)
{
    if (m_levels != arg) {
        m_levels = arg;
        emit levelsChanged(arg);
    }
}

void CharacterClass::setAcronym(QString arg)
{
    if (m_acronym != arg) {
        m_acronym = arg;
        emit acronymChanged(arg);
    }
}


